package com.sloth.bear.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sloth.bear.dto.entity.Navbar;
import com.sloth.bear.dto.request.NavbarRequest;
import com.sloth.bear.dto.request.NavbarSortUpdateRequest;
import com.sloth.bear.dto.vo.NavbarDetailsVo;
import com.sloth.bear.dto.vo.NavbarListVo;
import com.sloth.bear.mapper.NavbarMapper;
import com.sloth.bear.service.NavbarService;
import com.sloth.bear.util.AssertUtils;
import com.sloth.bear.util.BaseHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 导航栏服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NavbarServiceImpl extends ServiceImpl<NavbarMapper, Navbar> implements NavbarService {

    @Override
    public NavbarDetailsVo createNavbar(NavbarRequest request) {
        Navbar navbar = BaseHelper.r2t(request, Navbar.class);
        boolean result = save(navbar);
        AssertUtils.isTrue(result, "导航创建失败");
        return BaseHelper.r2t(navbar, NavbarDetailsVo.class);
    }

    @Override
    public List<NavbarListVo> listNavbar() {
        List<Navbar> navbarList = list(Wrappers.<Navbar>lambdaQuery()
                .orderByAsc(Navbar::getSortNo)
                .orderByDesc(Navbar::getCreatedTime));
        return getChildren(navbarList, null);
    }

    private List<NavbarListVo> getChildren(List<Navbar> navbarList, Long parentId) {
        List<NavbarListVo> result = new ArrayList<>();
        navbarList.stream().filter(o -> (parentId == null && o.getParentId() == null) ||
                        (parentId != null && parentId.equals(o.getParentId())))
                .forEach(o -> {
                    NavbarListVo vo = BaseHelper.r2t(o, NavbarListVo.class);
                    List<NavbarListVo> children = getChildren(navbarList, o.getId());
                    vo.setChildren(children);
                    result.add(vo);
                });
        return result;
    }

    @Override
    public NavbarDetailsVo detailsNavbar(Long id) {
        Navbar navbar = getById(id);
        AssertUtils.notNull(navbar, "导航不存在");
        return BaseHelper.r2t(navbar, NavbarDetailsVo.class);
    }

    @Override
    public NavbarDetailsVo updateNavbar(Long id, NavbarRequest request) {
        Navbar navbar = getById(id);
        AssertUtils.notNull(navbar, "导航不存在");

        BeanUtils.copyProperties(request, navbar);
        boolean result = updateById(navbar);
        AssertUtils.isTrue(result, "导航更新失败");
        return BaseHelper.r2t(navbar, NavbarDetailsVo.class);
    }

    @Override
    public Boolean deleteNavbar(Long id) {
        Navbar navbar = getById(id);
        AssertUtils.notNull(navbar, "导航不存在");

        long count = count(Wrappers.<Navbar>lambdaQuery().eq(Navbar::getParentId, id));
        AssertUtils.isTrue(count == 0, "请先删除子项");

        boolean result = removeById(id);
        AssertUtils.isTrue(result, "导航删除失败");
        return true;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateNavbarSort(NavbarSortUpdateRequest request) {
        AssertUtils.notNull(request, "请求参数不能为空");
        AssertUtils.isTrue(request.getItems() != null && !request.getItems().isEmpty(), "排序更新项列表不能为空");
        
        List<Navbar> updateList = new ArrayList<>();
        for (NavbarSortUpdateRequest.SortItem item : request.getItems()) {
            Navbar navbar = getById(item.getId());
            AssertUtils.notNull(navbar, "导航ID[" + item.getId() + "]不存在");
            
            navbar.setSortNo(item.getSortNo());
            updateList.add(navbar);
        }
        
        boolean result = updateBatchById(updateList);
        AssertUtils.isTrue(result, "批量更新排序失败");
        
        log.info("批量更新导航排序成功，共更新{}条记录", updateList.size());
        return true;
    }
}